package com.hg.library.graph;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.view.View;
import android.widget.HorizontalScrollView;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * Created by ASUS-PC on 2016/4/13.
 */
public class ImageProcess {

    public static Bitmap createReflectedImage(Bitmap originalImage) {
        return createReflectedImage(originalImage, originalImage.getHeight() / 2);
    }

    public static Bitmap createReflectedImage(Bitmap originalImage, int reflectH) {
        return createReflectedImage(originalImage, reflectH, 0x70ffffff, 0x00ffffff, 0);
    }

    public static Bitmap createReflectedImage(Bitmap originalImage, int reflectH, float reflectSpace) {
        return createReflectedImage(originalImage, reflectH, 0x70ffffff, 0x00ffffff, reflectSpace);
    }

    public static Bitmap createReflectedImage(Bitmap originalImage, int reflectH, int color0, int color1, float reflectSpace) {
        return createReflectedImage(originalImage, reflectH, color0, color1, reflectSpace, null, 0, 0);
    }

    public static Bitmap createReflectedAndShadowImage(Bitmap originalImage, Bitmap shadow, float leftOffset, float topOffset) {
        return createReflectedAndShadowImage(originalImage, originalImage.getHeight() / 2, 0, shadow, leftOffset, topOffset);
    }

    public static Bitmap createReflectedAndShadowImage(Bitmap originalImage, int reflectH, Bitmap shadow, float leftOffset, float topOffset) {
        return createReflectedAndShadowImage(originalImage, reflectH, 0, shadow, leftOffset, topOffset);
    }

    public static Bitmap createReflectedAndShadowImage(Bitmap originalImage, int reflectH, float reflectSpace, Bitmap shadow, float leftOffset, float topOffset) {
        return createReflectedImage(originalImage, reflectH, 0x70ffffff, 0x00ffffff, reflectSpace, shadow, leftOffset, topOffset);
    }

    public static Bitmap createReflectedImage(Bitmap originalImage, int reflectH, int color0, int color1, float reflectSpace, Bitmap shadow, float leftOffset, float topOffset) {
        int width, height;
        if (shadow != null) {
            width = shadow.getWidth();
            height = shadow.getHeight();
        } else {
            width = originalImage.getWidth();
            height = originalImage.getHeight();
        }
        if (reflectH > height)
            new IllegalAccessException("reflectH=" + reflectH + ";" + "height=" + height + ";" + "reflectH 不能大于 height");
        Matrix matrix = new Matrix();
        matrix.preScale(1, -1);
        Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, originalImage.getHeight() - reflectH, originalImage.getWidth(), reflectH, matrix, false);
        Bitmap finalReflection = Bitmap.createBitmap(width, (height + reflectH), Bitmap.Config.ARGB_8888);
        canvasReflectedImage(originalImage, reflectionImage, finalReflection, color0, color1, reflectSpace, shadow, leftOffset, topOffset);
        return finalReflection;
    }

    private static void canvasReflectedImage(Bitmap originalImage, Bitmap reflectionImage, Bitmap finalReflection, int color0, int color1, float reflectSpace, Bitmap shadow, float leftOffset, float topOffset) {
        Canvas canvas = new Canvas(finalReflection);
        canvas.drawBitmap(originalImage, leftOffset, topOffset, null);
        //把倒影图片画到画布上
        canvas.drawBitmap(reflectionImage, leftOffset, originalImage.getHeight() + topOffset + reflectSpace, null);
        Paint shaderPaint = new Paint();
        //创建线性渐变LinearGradient对象
        LinearGradient shader = new LinearGradient(0, originalImage.getHeight(), 0, finalReflection.getHeight() - topOffset * 3, color0,
                color1, Shader.TileMode.CLAMP);
        shaderPaint.setShader(shader);
        shaderPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        //画布画出反转图片大小区域，然后把渐变效果加到其中，就出现了图片的倒影效果。
        int width = originalImage.getWidth();
        if (shadow != null) width = shadow.getWidth();
        canvas.drawRect(0, originalImage.getHeight() + topOffset + 1, width, finalReflection.getHeight(), shaderPaint);
        if (shadow != null) canvas.drawBitmap(shadow, 0, 0, null);
    }

    public static JavaBlurProcess blurProcess = new JavaBlurProcess();

    /**
     * 高斯模糊处理 毛玻璃效果
     *
     * @param bitmap 位图
     * @param radius 模糊大小 不能下小于2
     * @return
     */
    public static Bitmap Blur(Bitmap bitmap, float radius) {
        return Blur(bitmap, -1, radius);
    }

    public static Bitmap Blur(Bitmap bitmap, int scale, float radius) {
        Bitmap bitmap2;
        if (scale < 0) {
            bitmap2 = blurProcess.blur(bitmap, radius);
            return bitmap2;
        }
        Bitmap bitmap1 = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth() / scale, bitmap.getHeight() / scale, false);
        bitmap2 = blurProcess.blur(bitmap1, radius);
        return bitmap2;
    }

    /**
     * 黑色模糊蒙版
     *
     * @param bitmap 位图
     * @param scale  位图缩放比例 小于0不缩放
     * @param radius 模糊大小 不能下小于2
     * @param Alpha  黑色透明度
     * @return bitmap
     */
    public static Bitmap BlackBlur(Bitmap bitmap, int scale, int radius, int Alpha) {
        return ColorBlur(Blur(bitmap, scale, radius), Color.Black, Alpha);
    }

    private static Bitmap ColorBlur(Bitmap bitmap, Color color, int Alpha) {
        float alpah = Alpha > 100 ? 1f : Alpha / 100f;
        float a = 1f - alpah;
        Bitmap bitmap1 = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap1);
        Paint paint = new Paint();
        if (color == Color.Black) {
            float[] floats = new float[]{
                    a, 0, 0, 0, 0,
                    0, a, 0, 0, 0,
                    0, 0, a, 0, 0,
                    0, 0, 0, 1, 0
            };
            paint.setColorFilter(new ColorMatrixColorFilter(floats));
        }
        canvas.drawBitmap(bitmap, 0, 0, paint);
        return bitmap1;
    }

    public enum Color {
        Black
    }

    /**
     * 获取圆角位图的方法
     *
     * @param bitmap 需要转化成圆角的位图
     * @param pixels 圆角的度数，数值越大，圆角越大
     * @return 处理后的圆角位图
     */
    public static Bitmap toRoundCorner(Bitmap bitmap, int pixels) {

        if (pixels == 0){
            return Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight());
        }

        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        final float roundPx = pixels;
        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
        return output;
    }

    public static byte[] Bitmap2Bytes(Bitmap bitmap) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
        byte[] bytes = outputStream.toByteArray();
        try {
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bytes;
    }

    public static Bitmap Bytes2Bitmap(byte[] bytes) {
        if (bytes.length != 0)
            return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        return null;
    }

    /**
     * @param originalImage
     * widgets include {@link ImageProcess#createReflectedImage(Bitmap)}
     */
    public static Bitmap createHalfReflectedImage(Bitmap originalImage) {
       return createHalfReflectedImage(originalImage,originalImage.getHeight() / 2);
    }

    public static Bitmap createHalfReflectedImage(Bitmap originalImage,int shadowH) {
        int width = originalImage.getWidth();
        int height = shadowH;
        Matrix matrix = new Matrix();
        matrix.preScale(1, -1);
        Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, originalImage.getHeight() - height, width, height, matrix, true);

        Canvas canvas = new Canvas(reflectionImage);
        Paint shaderPaint = new Paint();
        //创建线性渐变LinearGradient对象
        LinearGradient shader = new LinearGradient(0, 0, 0, height, 0x70ffffff,
                0x00ffffff, Shader.TileMode.CLAMP);
        shaderPaint.setShader(shader);
        shaderPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        //画布画出反转图片大小区域，然后把渐变效果加到其中，就出现了图片的倒影效果。
        canvas.drawRect(0, 1, originalImage.getWidth(), height, shaderPaint);
        return reflectionImage;
    }

    public static Bitmap drawable2Bitmap(Drawable drawable) {
        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        } else if (drawable instanceof NinePatchDrawable) {
            Bitmap bitmap = Bitmap
                    .createBitmap(
                            drawable.getIntrinsicWidth(),
                            drawable.getIntrinsicHeight(),
                            drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
                                    : Bitmap.Config.RGB_565);
            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
                    drawable.getIntrinsicHeight());
            drawable.draw(canvas);
            return bitmap;
        } else {
            return null;
        }
    }

    public static Drawable bitmap2Drawable(Resources resources,Bitmap bitmap) {
        return new BitmapDrawable(resources,bitmap);
    }

    public static Bitmap toCircleBitmap(Bitmap bitmap,int min){
        Paint paint = new Paint();

        Bitmap bitmap1 = Bitmap.createScaledBitmap(bitmap,min,min,true);

        Bitmap bitmap2 = Bitmap.createBitmap(bitmap1.getWidth(),bitmap1.getHeight(), Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(bitmap2);

        paint.setAntiAlias(true);

        canvas.drawCircle(min/2,min/2,min/2,paint);

        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

        canvas.drawBitmap(bitmap1,0,0,paint);

        return bitmap2;
    }

    public static Bitmap getViewBlur(View view){
        view.setDrawingCacheEnabled(true);
        Bitmap drawingCache = view.getDrawingCache();
        if (drawingCache == null){
            return null;
        }
        Bitmap blur = Blur(drawingCache, 8, 8);
        view.setDrawingCacheEnabled(false);
        return blur;
    }

}
